package com.example.forum.controller;

import com.example.forum.entity.User;
import com.example.forum.exception.CustomException;
import com.example.forum.result.Result;
import com.example.forum.services.impl.UserServiceImpl;
import com.example.forum.utils.MD5Util;
import com.example.forum.utils.UUIDUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import static com.example.forum.constant.MessageConstant.*;

@Slf4j
@RestController
@RequestMapping("/user")
@Tag(name = "用户接口")
public class UserController {

    @Autowired
    private UserServiceImpl userService;

    /**
     * 用户注册
     *
     * @param username       用户名
     * @param password       密码
     * @param nickname       昵称
     * @param passwordRepeat 确认密码
     * @return Result
     */
    @Operation(summary = "用户注册")
    @PostMapping("/register")
    public Result register(@Parameter(description = "用户名") @RequestParam("username") @NotNull String username,
                           @Parameter(description = "密码") @RequestParam("password") @NotNull String password,
                           @Parameter(description = "昵称") @RequestParam("nickname") @NotNull String nickname,
                           @Parameter(description = "确认密码") @RequestParam("passwordRepeat") @NotNull String passwordRepeat) {
        // 校验密码是否相同
        if (!password.equals(passwordRepeat)) {
            return Result.error(PASSWORD_NOT_SAME);
        }
        // 生成盐
        String salt = UUIDUtil.UUID_32();
        // 密码加密
        String md5Salt = MD5Util.md5Salt(password, salt);
        // 封装用户信息
        User user = new User();
        user.setUsername(username);
        user.setNickname(nickname);
        user.setPassword(md5Salt);
        user.setSalt(salt);
        // 注册逻辑
        try {
            userService.register(user);
            return Result.success(USER_REGISTER_SUCCESS);
        } catch (CustomException e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @return Result
     */
    @Operation(summary = "用户登录")
    @PostMapping("/login")
    public Result login(HttpServletRequest request,
                        @Parameter(description = "用户名") @RequestParam("username") @NotNull String username,
                        @Parameter(description = "密码") @RequestParam("password") @NotNull String password) {
        // 登录逻辑
        try {
            User user = userService.login(username, password);
            HttpSession session = request.getSession(true);
            session.setAttribute(USER_SESSION, user);
            log.info(USER_LOGIN_SUCCESS + "用户id: {}", user.getId());
            return Result.success();
        } catch (CustomException e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取用户信息
     *
     * @param request 请求
     * @param id      用户id
     * @return Result
     */
    @Operation(summary = "获取用户信息")
    @GetMapping("/info")
    public Result<User> getUser(HttpServletRequest request,
                                @Parameter(description = "用户id") @RequestParam(value = "id", required = false) Long id) {
        User user;
        if (id == null) {
            HttpSession session = request.getSession(false);
            user = (User) session.getAttribute(USER_SESSION);
        } else {
            try {
                user = userService.getUser(id);
            } catch (CustomException e) {
                log.error(e.getMessage());
                return Result.error(e.getMessage());
            }
        }
        return Result.success(user);
    }

    /**
     * 退出登录
     *
     * @param request 请求
     * @return Result
     */
    @Operation(summary = "退出登录")
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        log.info("退出成功");
        return Result.success(USER_LOGOUT_SUCCESS);
    }

    /**
     * 修改用户信息
     *
     * @param request  请求
     * @param username 用户名
     * @param nickname 昵称
     * @param gender   性别
     * @param email    邮箱
     * @param phoneNum 手机号
     * @param remark   个人简介
     * @return Result
     */
    @Operation(summary = "修改用户信息")
    @PostMapping("/modifyInfo")
    public Result<User> modifyInfo(HttpServletRequest request,
                                   @Parameter(description = "用户名") @RequestParam(value = "username", required = false) String username,
                                   @Parameter(description = "用户呢称") @RequestParam(value = "nickname", required = false) String nickname,
                                   @Parameter(description = "性别") @RequestParam(value = "gender", required = false) Integer gender,
                                   @Parameter(description = "邮箱") @RequestParam(value = "email", required = false) String email,
                                   @Parameter(description = "手机号") @RequestParam(value = "phoneNum", required = false) String phoneNum,
                                   @Parameter(description = "个人简介") @RequestParam(value = "remark", required = false) String remark) {

        // 获取用户信息
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(USER_SESSION);

        if (user == null) {
            return Result.error(USER_NOT_LOGIN);
        }
        Long id = user.getId();

        // 修改用户信息
        try {
            userService.modifyInfo(id, username, nickname, gender, email, phoneNum, remark);

            // 查寻用户信息
            user = userService.getUser(id);
            // 更新session
            session.setAttribute(USER_SESSION, user);

            return Result.success(user);
        } catch (CustomException e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 修改密码
     *
     * @param request      请求
     * @param oldPwd       旧密码
     * @param newPwd       新密码
     * @param newPwdRepeat 确认密码
     * @return Result
     */
    @Operation(summary = "修改密码")
    @PostMapping("/modifyPwd")
    public Result<User> modifyPwd(HttpServletRequest request,
                                  @Parameter(description = "旧密码") @RequestParam(value = "oldPassword") @NotNull String oldPwd,
                                  @Parameter(description = "新密码") @RequestParam(value = "newPassword") @NotNull String newPwd,
                                  @Parameter(description = "确认密码") @RequestParam(value = "passwordRepeat") @NotNull String newPwdRepeat) {
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(USER_SESSION);
        // 判断用户是否登录
        if (user == null) {
            return Result.error(USER_NOT_LOGIN);
        }
        // 比较新密码和确认密码是否一致
        if (!newPwd.equals(newPwdRepeat)) {
            return Result.error(PASSWORD_NOT_SAME);
        }
        try {
            userService.modifyPwd(user, oldPwd, newPwd);
            // 查询用户信息
            user = userService.getUser(user.getId());
            // 更新session
            session.setAttribute(USER_SESSION, user);

            return Result.success(user);

        } catch (CustomException e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }
}
